--- title: "春晚刘谦魔术 约瑟夫问题" created: 2025-11-28 tags: - 算法 --- # 春晚刘谦魔术 约瑟夫问题 ```cpp #include #include #include #include using namespace std; vector arr; void printArray(const vector& arr) { cout << "当前手上牌的状态:" << endl; for (auto num : arr) { cout << num << ' '; } cout << '\n'; } int main() { //第一步:选4张扑克牌 弄乱它(弄不弄其实乱无所谓) vector cards(4); cout << "输入4张扑克牌的数字(1-13)(花色忽略 为方便检验请不要输入相同数字):" << endl; for (int i = 0; i < 4; ++i) { cin >> cards[i]; } //第二步:对折 撕开它们 arr.insert(arr.end(), cards.begin(), cards.end()); arr.insert(arr.end(), cards.begin(), cards.end()); //第三步:名字几个字 就循环把第一张放在最下面几次 int name_length; cout << "输入名字的长度:"; cin >> name_length; rotate(arr.begin(), arr.begin() + name_length % arr.size(), arr.end()); printArray(arr); //第四步:把前3张卡片放在中间的任意位置(小尼老师这样做错了hhh 他好像是放在了最下面) int middle = arr.size() / 2; vector temp(arr.begin(), arr.begin() + 3); arr.erase(arr.begin(), arr.begin() + 3); arr.insert(arr.begin() + middle, temp.begin(), temp.end()); printArray(arr); // 第五步:把第一张卡片藏在屁股下面 //(其实这里就已经出答案了 第一个元素等于最后一个元素 后面是约瑟夫问题) int drawn_card = arr.front(); arr.erase(arr.begin()); cout << endl << "剧透一下现在抽掉的是:" << drawn_card << endl << endl; printArray(arr); //第六步:南方人拿走1张 北方人拿走2张 不确定拿走3张 然后插到中间 // 根据条件抽走或者插入元素,假设根据南北方插入 cout << "您是南(1)/北(2)/不确定(3):(输入1/2/3即可)" << endl; int direction; cin >> direction; int num_to_move = 0; if (direction == 1) { num_to_move = 1; } else if (direction == 2) { num_to_move = 2; } else if (direction == 3) { num_to_move = 3; } else { cout << "输入错误!懒得做防刁民的措施 别试了" << endl; return 1; } vector top_cards(arr.begin(), arr.begin() + num_to_move); arr.erase(arr.begin(), arr.begin() + num_to_move); int middle2 = arr.size() / 2; arr.insert(arr.begin() + middle2, top_cards.begin(), top_cards.end()); printArray(arr); //第七步:男生扔掉顶上的1张 女生扔掉顶上的2张 cout << "您是男生还是女生?(男1/女2):" << endl; int gender; cin >> gender; if (gender == 1) { arr.erase(arr.begin()); } else if (gender == 2) { arr.erase(arr.begin(), arr.begin() + 2); } else { cout << "输入错误!懒得做防刁民的措施 别试了" << endl; return 1; } printArray(arr); // 第八步:“见证奇迹的时刻” cout << "来点仪式感! 输入:见证奇迹的时刻" << endl; string magic_words; cin.ignore(); getline(cin, magic_words); //int words_count = magic_words.size();//编码问题 算不出7个 所以写死7吧 for (int i = 0; i < 7; ++i) { int card_to_move = arr.front(); arr.erase(arr.begin()); arr.push_back(card_to_move); } printArray(arr); //最后环节 好运留下来 烦恼丢出去 奇数张放在底部 偶数张丢弃 while (arr.size() > 1) { // 第1张放到最下面 int card_to_bottom = arr.front(); arr.erase(arr.begin()); arr.push_back(card_to_bottom); // 打印操作后的数组状态 printArray(arr); // 第2张扔出去 if (arr.size() > 1) { arr.erase(arr.begin()); } // 打印操作后的数组状态 printArray(arr); } //有问题 想用算法解决的 但是太菜了 只能用模拟了 //int step = 3; //int index = 0; //while (arr.size() > 1) { // index = (index + step - 1) % arr.size(); // arr.erase(arr.begin() + index); // printArray(arr); //} // 输出最后一张牌 cout << "最后一张牌: " << arr.front() << '\n'; return 0; } ``` --- ⬅️ [[在O(1)时间删除链表结点|在O(1)时间删除链表结点]] 🏠 [[00-刷题理模型]] ➡️ [[2-Learning/02-算法/03-刷题理模型/链表相关问题/栈|栈]]